/**
 * Copyright © 2013 Creativor Studio.
 * About license information, please see LICENSE.txt.
 */
package org.creativor.rayson.share.transport.http;

import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.creativor.rayson.share.annotation.NotNull;
import org.creativor.rayson.share.transport.BufferWritable;
import org.creativor.rayson.share.transport.ByteArrayBuffer;
import org.creativor.rayson.util.LangUtil;

/**
 * HTTP headers manager object.
 * 
 * @author creativor
 */
public class HttpHeaders implements BufferWritable {
	/**
	 * Test whether one header is an
	 * {@value HttpConstants#CONTENT_LENGTH_HEADER_NAME} one.
	 * 
	 * @param header
	 *            Header to be test.
	 */
	public static boolean isContentLength(@NotNull final HttpHeader header) {

		return header.getName()
				.equals(HttpConstants.CONTENT_LENGTH_HEADER_NAME);
	}

	private final Map<String, HttpHeader> map;

	HttpHeaders() {
		map = new HashMap<>();
	}

	/**
	 * Add a header to this container.
	 * 
	 * @param header
	 *            Header to be added.
	 * @throws HttpProtocolException
	 */
	public void add(@NotNull final HttpHeader header)
			throws HttpProtocolException {
		LangUtil.testNullArgument(header);
		map.put(header.getName(), header);
	}

	/**
	 * Get an HTTP header by given an name.
	 * 
	 * @param name
	 *            Header name.
	 * @return Found header. Or null if found none.
	 */
	public HttpHeader get(@NotNull final String name) {
		LangUtil.testNullArgument(name);
		return map.get(name);
	}

	/**
	 * @return Iterator of all headers. Unmodifiable.
	 */
	public Iterator<HttpHeader> iterator() {
		return Collections.unmodifiableMap(map).values().iterator();
	}

	/**
	 * Remove a header.
	 * 
	 * @param name
	 *            Header name to be removed.
	 */
	public void remove(@NotNull final String name) {
		LangUtil.testNullArgument(name);
		this.map.remove(name);
	}

	/**
	 * Setup an header.
	 * 
	 * @param name
	 *            Header name.
	 * @param value
	 *            Header value.
	 */
	public void set(@NotNull final String name, @NotNull final String value) {
		final HttpHeader header = new HttpHeader(name, value);
		map.put(name, header);
	}

	@Override
	public String toString() {
		final StringBuffer sb = new StringBuffer();
		sb.append("[");
		for (final HttpHeader header : map.values()) {
			sb.append(header);
			sb.append(", ");
		}
		final int length = sb.length();
		if (length > 2) {
			sb.delete(length - 2, length);
		}
		sb.append("]");
		return sb.toString();
	}

	@Override
	public void writeTo(final ByteArrayBuffer buffer) {
		for (final HttpHeader header : map.values()) {
			header.writeTo(buffer);
		}
	}
}
